home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / grapdrvs / gen_grap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-02  |  22.5 KB  |  734 lines

  1. /*****************************************************************************
  2. *   General routines common to graphics driver.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, June 1993.  *
  5. *****************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include "irit_sm.h"
  11. #include "genmat.h"
  12. #include "getarg.h"
  13. #include "config.h"
  14. #include "iritprsr.h"
  15. #include "allocate.h"
  16. #include "attribut.h"
  17. #include "iritgrap.h"
  18. #include "irit_soc.h"
  19.  
  20. #ifdef OS2GCC
  21. #define INCL_DOSPROCESS
  22. #include <os2.h>
  23. #endif /* OS2GCC */
  24.  
  25. #define MAX_ROTATE_ANGLE    45.0 /* Max. rates used by interactive mode. */
  26. #define MAX_TRANSLATE_FACTOR    2.0
  27. #define MAX_SCALE_FACTOR    2.0
  28. #define MAX_CLIP_FACTOR        0.5
  29.  
  30. typedef struct StateNameNumType {
  31.    IGGlblStateType Num;
  32.    char *Name;
  33. } StateNameNumType;
  34.  
  35. static StateNameNumType StateNameNum[] =
  36. {
  37.     { IG_STATE_MORE_SENSITIVE,        "MoreSense" },
  38.     { IG_STATE_LESS_SENSITIVE,        "LessSense" },
  39.     { IG_STATE_SCR_OBJ_TGL,        "ScrnObjct" },
  40.     { IG_STATE_PERS_ORTHO_TGL,        "PerpsOrtho" },
  41.     { IG_STATE_DEPTH_CUE,        "DepthCue" },
  42.     { IG_STATE_DRAW_SOLID,        "DrawSolid" },
  43.     { IG_STATE_DOUBLE_BUFFER,        "DblBuffer" },
  44.     { IG_STATE_ANTI_ALIASING,        "AntiAlias" },
  45.     { IG_STATE_DRAW_INTERNAL,        "DrawIntrnl" },
  46.     { IG_STATE_DRAW_VNORMAL,        "DrawVNrml" },
  47.     { IG_STATE_DRAW_PNORMAL,        "DrawPNrml" },
  48.     { IG_STATE_DRAW_SRF_MESH,        "DSrfMesh" },
  49.     { IG_STATE_DRAW_SRF_POLY,        "DSrfPoly" },
  50.     { IG_STATE_FOUR_PER_FLAT,        "4PerFlat" },
  51.     { IG_STATE_MORE_ISOLINES,        "MoreIso" },
  52.     { IG_STATE_LESS_ISOLINES,        "LessIso" },
  53.     { IG_STATE_FINER_APPROX,        "FinrAprx" },
  54.     { IG_STATE_COARSER_APPROX,        "CrsrAprx" },
  55.     { IG_STATE_LONGER_VECTORS,        "LngrVecs" },
  56.     { IG_STATE_SHORTER_VECTORS,        "ShrtrVecs" },
  57.     { IG_STATE_WIDER_LINES,        "WiderLns" },
  58.     { IG_STATE_NARROW_LINES,        "NarrwLns" },
  59.     { IG_STATE_FINER_ADAP_ISO,        "FinrAdapIso" },
  60.     { IG_STATE_COARSER_ADAP_ISO,    "CRsrAdapIso" },
  61.     { IG_STATE_FINER_RULED_SRF,        "FinerRld" },
  62.     { IG_STATE_COARSER_RULED_SRF,    "CrsrRld" },
  63.     { IG_STATE_RULED_SRF_APPROX,    "RuledSrfApx" },
  64.     { IG_STATE_ADAP_ISO_DIR,        "AdapIsoDir" },
  65.     { IG_STATE_VIEW_FRONT,        "Front" },
  66.     { IG_STATE_VIEW_SIDE,        "Side" },
  67.     { IG_STATE_VIEW_TOP,        "Top" },
  68.     { IG_STATE_VIEW_ISOMETRY,        "Isometry" },
  69.     { 0,                NULL }
  70. };
  71.  
  72. static int
  73.     GlblDelayedClear = FALSE,
  74.     GlblProcessCommandMesssages = TRUE,
  75.     GlblNormalLenAux = 200;
  76.  
  77. static MatrixType PushViewMat, PushPrspMat;
  78. static MatrixType IsometryViewMat = {          /* Isometric view, by default. */
  79.     { -0.707107, -0.408248, 0.577350, 0.000000 },
  80.     {  0.707107, -0.408248, 0.577350, 0.000000 },
  81.     {  0.000000,  0.816496, 0.577350, 0.000000 },
  82.     {  0.000000,  0.000000, 0.000000, 1.000000 }
  83. };
  84.  
  85. #ifdef __UNIX__
  86. static char
  87.     *GlblBackGroundStr = "20 20 20";
  88.  
  89. int IGGlblBackGroundColor[3] = { 20, 20, 20 },
  90. #else
  91. static char
  92.     *GlblBackGroundStr = "63 63 63";
  93.  
  94. int IGGlblBackGroundColor[3] = { 63, 63, 63 },
  95. #endif /* __UNIX__ */
  96.     IGGlblDrawInternal = FALSE,
  97.     IGGlblDrawVNormal = FALSE,
  98.     IGGlblDrawPNormal = FALSE,
  99.     IGGlblMore = FALSE,
  100.     IGGlblForceUnitMat = FALSE,
  101.     IGGlblDrawSolid = FALSE,
  102.     IGGlblDoDoubleBuffer = TRUE,
  103.     IGGlblNumOfIsolines = 8,
  104.     IGGlblSamplesPerCurve = 6,
  105.     IGGlblLineWidth = 1,
  106.     IGGlblAdapIsoDir = CAGD_CONST_U_DIR,
  107.     IGGlblFineNess = 5,
  108.     IGGlblDepthCue = TRUE,
  109.     IGGlblFourPerFlat = TRUE,
  110.     IGGlblAntiAliasing = TRUE,
  111.     IGGlblDrawSurfaceMesh = FALSE,
  112.     IGGlblDrawSurfacePoly = FALSE,
  113.     IGGlblStandAlone = TRUE,
  114.     IGGlblTransformMode = IG_TRANS_SCREEN,
  115.     IGGlblViewMode = IG_VIEW_PERSPECTIVE,
  116.     IGGlblDebugObjectsFlag = FALSE,
  117.     IGGlblDebugEchoInputFlag = FALSE,
  118.     IGGlblIntensityHighState = TRUE,
  119.     IGGlblDisplayListIsUsed = FALSE,
  120.     IGGlblAbortKeyPressed = FALSE,
  121.     IGGlblNumFiles;
  122.  
  123. char
  124.     *IGGlblTransPrefPos = "455, 640, 520, 965",
  125.     *IGGlblViewPrefPos = "1,   450, 520, 965",
  126.     **IGGlblFileNames;
  127.  
  128. RealType
  129.     IGGlblChangeFactor = 1.0,
  130.     IGGlblZMinClip = -2.0,
  131.     IGGlblZMaxClip = 2.0,
  132.     IGGlblNormalLen = 0.2;
  133.  
  134. MatrixType IGGlblCrntViewMat;
  135.  
  136. IPObjectStruct
  137.     *IGGlblDisplayList = NULL;
  138.  
  139. static ConfigStruct SetUp[] =
  140. {
  141.   { "TransPrefPos",    (VoidPtr) &IGGlblTransPrefPos,    SU_STRING_TYPE },
  142.   { "ViewPrefPos",    (VoidPtr) &IGGlblViewPrefPos,    SU_STRING_TYPE },
  143.   { "BackGround",    (VoidPtr) &GlblBackGroundStr,    SU_STRING_TYPE },
  144.   { "Internal",        (VoidPtr) &IGGlblDrawInternal,    SU_BOOLEAN_TYPE },
  145.   { "DrawVNormal",    (VoidPtr) &IGGlblDrawVNormal,    SU_BOOLEAN_TYPE },
  146.   { "DrawPNormal",    (VoidPtr) &IGGlblDrawPNormal,    SU_BOOLEAN_TYPE },
  147.   { "MoreVerbose",    (VoidPtr) &IGGlblMore,        SU_BOOLEAN_TYPE },
  148.   { "UnitMatrix",    (VoidPtr) &IGGlblForceUnitMat,    SU_BOOLEAN_TYPE },
  149.   { "DrawSolid",    (VoidPtr) &IGGlblDrawSolid,    SU_BOOLEAN_TYPE },
  150.   { "DoubleBuffer",    (VoidPtr) &IGGlblDoDoubleBuffer,SU_BOOLEAN_TYPE },
  151.   { "NumOfIsolines",    (VoidPtr) &IGGlblNumOfIsolines,    SU_INTEGER_TYPE },
  152.   { "SamplesPerCurve",    (VoidPtr) &IGGlblSamplesPerCurve, SU_INTEGER_TYPE },
  153.   { "LineWidth",    (VoidPtr) &IGGlblLineWidth,    SU_INTEGER_TYPE },
  154.   { "AdapIsoDir",    (VoidPtr) &IGGlblAdapIsoDir,    SU_INTEGER_TYPE },
  155.   { "FineNess",        (VoidPtr) &IGGlblFineNess,    SU_INTEGER_TYPE },
  156.   { "DepthCue",        (VoidPtr) &IGGlblDepthCue,    SU_BOOLEAN_TYPE },
  157.   { "FourPerFlat",    (VoidPtr) &IGGlblFourPerFlat,    SU_BOOLEAN_TYPE },
  158.   { "AntiAlias",    (VoidPtr) &IGGlblAntiAliasing,    SU_BOOLEAN_TYPE },
  159.   { "DrawSurfaceMesh",    (VoidPtr) &IGGlblDrawSurfaceMesh, SU_BOOLEAN_TYPE },
  160.   { "DrawSurfacePoly",    (VoidPtr) &IGGlblDrawSurfacePoly, SU_BOOLEAN_TYPE },
  161.   { "StandAlone",    (VoidPtr) &IGGlblStandAlone,    SU_BOOLEAN_TYPE },
  162.   { "TransMode",    (VoidPtr) &IGGlblTransformMode,    SU_INTEGER_TYPE },
  163.   { "ViewMode",        (VoidPtr) &IGGlblViewMode,    SU_INTEGER_TYPE },
  164.   { "NormalLength",    (VoidPtr) &GlblNormalLenAux,    SU_INTEGER_TYPE },
  165.   { "DebugObjects",    (VoidPtr) &IGGlblDebugObjectsFlag, SU_BOOLEAN_TYPE },
  166.   { "DebugEchoInput",    (VoidPtr) &IGGlblDebugEchoInputFlag, SU_BOOLEAN_TYPE },
  167. };
  168. #define NUM_SET_UP    (sizeof(SetUp) / sizeof(ConfigStruct))
  169.  
  170. #ifdef NO_CONCAT_STR
  171. static char
  172.     *GenVersionStr = "     Version 4.0,    Gershon Elber,\n\
  173.     (C) Copyright 1989/90/91/92/93 Gershon Elber, Non commercial use only.";
  174. #else
  175. static char
  176.     *GenVersionStr = "    " VERSION ",    Gershon Elber,    "
  177.     __DATE__ ",   " __TIME__ "\n"
  178.     "(C) Copyright 1989/90/91/92/93 Gershon Elber, Non commercial use only.";
  179. #endif /* NO_CONCAT_STR */
  180.  
  181. static char
  182.     *GenCtrlStr = " s%- u%- n%- N%- i%- c%- m%- I%-#IsoLines!d S%-#SampPerCrv!d f%-FineNess!d l%-LineWidth!d d%- D%- L%-NormalLen!d 4%- b%-BackGround!d!d!d M%- P%- z%- DFiles!*s";
  183.  
  184. static void AddReplaceObjDisplayList(IPObjectStruct **DisplayList,
  185.                      IPObjectStruct *NewObj, char *ObjName);
  186.  
  187. /****************************************************************************
  188. * Set up configuration of global variables.                    *
  189. ****************************************************************************/
  190. void IGConfigureGlobals(char *PrgmName, int argc, char **argv)
  191. {
  192.     int Error,
  193.     IsoLinesFlag = FALSE,
  194.     SamplesPerCurveFlag = FALSE,
  195.     FinenessFlag = FALSE,
  196.     LineWidthFlag = FALSE,
  197.     NormalLenFlag = FALSE,
  198.     BackGroundFlag = FALSE,
  199.     VerFlag = FALSE;
  200.     char Line[LINE_LEN_LONG];
  201.  
  202.     Config(PrgmName, SetUp, NUM_SET_UP);   /* Read config. file if exists. */
  203.  
  204.     sscanf(GlblBackGroundStr, "%d %d %d",
  205.        &IGGlblBackGroundColor[0],
  206.        &IGGlblBackGroundColor[1],
  207.        &IGGlblBackGroundColor[2]);
  208.  
  209.     strcpy(Line, PrgmName);
  210.     strcat(Line, GenCtrlStr);
  211.     if ((Error = GAGetArgs(argc, argv, Line,
  212.                &IGGlblStandAlone, &IGGlblForceUnitMat,
  213.                &IGGlblDrawVNormal, &IGGlblDrawPNormal,
  214.                &IGGlblDrawInternal, &IGGlblDepthCue,
  215.                &IGGlblMore, &IsoLinesFlag, &IGGlblNumOfIsolines,
  216.                &SamplesPerCurveFlag, &IGGlblSamplesPerCurve,
  217.                &FinenessFlag, &IGGlblFineNess,
  218.                &LineWidthFlag, &IGGlblLineWidth,
  219.                &IGGlblDebugObjectsFlag, &IGGlblDebugEchoInputFlag,
  220.                &NormalLenFlag, &GlblNormalLenAux,
  221.                &IGGlblFourPerFlat, &BackGroundFlag,
  222.                &IGGlblBackGroundColor[0], &IGGlblBackGroundColor[1],
  223.                &IGGlblBackGroundColor[2],
  224.                &IGGlblDrawSurfaceMesh, &IGGlblDrawSurfacePoly,
  225.                &VerFlag, &IGGlblNumFiles, &IGGlblFileNames)) != 0) {
  226.     GAPrintErrMsg(Error);
  227.     GAPrintHowTo(Line);
  228.     exit(1);
  229.     }
  230.  
  231.     if (VerFlag) {
  232.     fprintf(stderr, "\n%s%s\n\n", PrgmName, GenVersionStr);
  233.     GAPrintHowTo(Line);
  234.     ConfigPrint(SetUp, NUM_SET_UP);
  235.     exit(0);
  236.     }
  237.  
  238.     if (IGGlblDebugEchoInputFlag)
  239.     SocClientEchoInput(TRUE);
  240.  
  241.     IGGlblNormalLen = GlblNormalLenAux / 1000.0;
  242.  
  243.     if (IGGlblAdapIsoDir == 1)
  244.     IGGlblAdapIsoDir = CAGD_CONST_U_DIR;
  245.     else if (IGGlblAdapIsoDir == 2)
  246.     IGGlblAdapIsoDir = CAGD_CONST_V_DIR;
  247.  
  248.     /* Get the data files: */
  249.     if (IGGlblNumFiles > 0) {
  250.     IGGlblDisplayList = IritPrsrGetDataFiles(IGGlblFileNames,
  251.                          IGGlblNumFiles, TRUE, TRUE);
  252.     IGGlblViewMode = IritPrsrWasPrspMat ? IG_VIEW_PERSPECTIVE
  253.                         : IG_VIEW_ORTHOGRAPHIC;
  254.     if (IGGlblForceUnitMat) {
  255.         MatGenUnitMat(IritPrsrViewMat);
  256.         IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC;
  257.     }
  258.     }
  259.  
  260.     GEN_COPY(PushViewMat, IritPrsrViewMat, sizeof(MatrixType));
  261.     GEN_COPY(PushPrspMat, IritPrsrPrspMat, sizeof(MatrixType));
  262. }
  263.  
  264. /****************************************************************************
  265. * Set up configuration of global variables.                    *
  266. ****************************************************************************/
  267. void IGProcessCommandMessages(int ProcessCommandMessages)
  268. {
  269.     GlblProcessCommandMesssages = ProcessCommandMessages;
  270. }
  271.  
  272. /*****************************************************************************
  273. * Routine to attempt and read an object from communication socket.         *
  274. *   Returns TRUE if screen needs to be redrawn in the case that the         *
  275. * DisplayList was modified.                             *
  276. *   This function DOES NOT BLOCK if no input is available.             *
  277. *   Handles commands via a string object with name "COMMAND_".             *
  278. *****************************************************************************/
  279. int IGReadObjectsFromSocket(int ViewMode, IPObjectStruct **DisplayList)
  280. {
  281.     int Redraw = FALSE;
  282.  
  283.     IPObjectStruct *PObjs;
  284.  
  285.     if ((PObjs = SocClientReadOneObject()) != NULL) {
  286.     IPObjectStruct *PObj;
  287.  
  288. #       ifdef __WINNT__
  289.         /* Slim chance that a race will oocur if the following test and */
  290.         /* set is done simultanuously. Should use semaphors probably.   */
  291.         while (IGGlblDisplayListIsUsed)
  292.             IritSleep(10);
  293.         IGGlblDisplayListIsUsed = TRUE;
  294. #    endif /* __WINNT__ */
  295. #    ifdef OS2GCC
  296.     while (IGGlblDisplayListIsUsed) {
  297.         IritSleep(10);
  298.         DosEnterCritSec();
  299.         if (!IGGlblDisplayListIsUsed) {
  300.         IGGlblDisplayListIsUsed = TRUE;
  301.         DosExitCritSec();
  302.         break;
  303.         }
  304.         DosExitCritSec();
  305.     }
  306. #    endif /* OS2GCC */
  307.  
  308.     Redraw = TRUE;
  309.  
  310.     if (GlblDelayedClear) {
  311. #        ifdef OS2GCC
  312.             /* For some reason without this delay, this  */
  313.             /* driver crashes on command toggles.         */
  314.         IritSleep(100);
  315. #        endif /* OS2GCC */
  316.         GlblDelayedClear = FALSE;
  317.         IPFreeObjectList(*DisplayList);
  318.         *DisplayList = NULL;
  319.     }
  320.  
  321.     while (PObjs != NULL) {
  322.         PObj = PObjs;
  323.         PObjs = PObjs -> Pnext;
  324.         PObj -> Pnext = NULL;
  325.  
  326.         if (IGGlblDebugObjectsFlag)
  327.         IritPrsrPutObject(stdout, PObj);
  328.  
  329.         if (GlblProcessCommandMesssages) {
  330.         switch (PObj -> ObjType) {
  331.             case IP_OBJ_STRING:
  332.                 if (stricmp(PObj -> Name, "COMMAND_") == 0) {
  333.                 char
  334.                 *Str = PObj -> U.Str;
  335.  
  336. #                ifdef OS2GCC
  337.                     /* For some reason without this delay, this  */
  338.                     /* driver crashes on command toggles.         */
  339.                 IritSleep(300);
  340. #                endif /* OS2GCC */
  341.                 if (stricmp(Str, "CLEAR") == 0) {
  342.                 IPFreeObjectList(*DisplayList);
  343.                 *DisplayList = NULL;
  344.                 }
  345.                 if (stricmp(Str, "DCLEAR") == 0) {
  346.                 GlblDelayedClear = TRUE;
  347.                 Redraw = FALSE;
  348.                 }
  349.                 else if (strnicmp(Str, "MSAVE", 5) == 0) {
  350.                 IGSaveCurrentMat(ViewMode, &PObj -> U.Str[6]);
  351.                 Redraw = FALSE;
  352.                 }
  353.                 else if (strnicmp(Str, "REMOVE", 6) == 0) {
  354.                 AddReplaceObjDisplayList(DisplayList, NULL,
  355.                             &PObj -> U.Str[7]);
  356.                 Redraw = TRUE;
  357.                 }
  358.                 else if (stricmp(Str, "DISCONNECT") == 0) {
  359.                 SocClientCloseSocket();
  360.                 Redraw = FALSE;
  361.                 }
  362.                 else if (stricmp(Str, "EXIT") == 0) {
  363.                 SocClientCloseSocket();
  364.                 exit(0);
  365.                 }
  366.                 else if (stricmp(Str, "BEEP") == 0) {
  367.                 IGIritBeep();
  368.                 Redraw = FALSE;
  369.                 }
  370.                 else if (strnicmp(Str, "STATE", 5) == 0) {
  371.                 int i;
  372.  
  373.                 Str = &Str[6];
  374.  
  375.                 for (i = 0;
  376.                      StateNameNum[i].Name != NULL;
  377.                      i++) {
  378.                     if (stricmp(Str,
  379.                         StateNameNum[i].Name) == 0) {
  380.                     IGHandleState(StateNameNum[i].Num,
  381.                               TRUE);
  382.                     break;
  383.                     }
  384.                 }
  385.                 }
  386.             }
  387.             IPFreeObject(PObj);
  388.             break;
  389.             case IP_OBJ_MATRIX:
  390.             if (stricmp(PObj -> Name, "VIEW_MAT") == 0) {
  391.                 GEN_COPY(IritPrsrViewMat, *PObj -> U.Mat,
  392.                      sizeof(MatrixType));
  393.             }
  394.             else if (stricmp(PObj -> Name, "PRSP_MAT") == 0) {
  395.                 GEN_COPY(IritPrsrPrspMat, *PObj -> U.Mat,
  396.                      sizeof(MatrixType));
  397.             }
  398.             IPFreeObject(PObj);
  399.             break;
  400.             default:
  401.             AddReplaceObjDisplayList(DisplayList, PObj, NULL);
  402.             break;
  403.         }
  404.         }
  405.         else {
  406.         AddReplaceObjDisplayList(DisplayList, PObj, NULL);
  407.         }
  408.     }
  409.  
  410.     IGGlblDisplayListIsUsed = FALSE;
  411.  
  412.     return Redraw;
  413.     }
  414.     else
  415.     return Redraw;
  416. }
  417.  
  418. /****************************************************************************
  419. * Add or replace an object on the display list.                    *
  420. *   If ObjName is not NULL, that object is removed from the display list.   *
  421. *   Otherwise NewObj is added to the display list, possibly replacing an    *
  422. * object on the display list with the same name.                *
  423. ****************************************************************************/
  424. static void AddReplaceObjDisplayList(IPObjectStruct **DisplayList,
  425.                      IPObjectStruct *NewObj, char *ObjName)
  426. {
  427.     int Remove = ObjName != NULL;
  428.     char
  429.     *Name = ObjName != NULL ? ObjName : NewObj -> Name;
  430.     IPObjectStruct *PObj;
  431.  
  432.     /* If object has no name or display list is empty, add it. */
  433.     if (!Remove &&
  434.     NewObj != NULL &&
  435.     (stricmp(NewObj -> Name, "none") == 0 ||
  436.      strlen(NewObj -> Name) == 0)) {
  437.     NewObj -> Pnext = *DisplayList;
  438.     *DisplayList = NewObj;
  439.     return;
  440.     }
  441.     if (*DisplayList == NULL) {
  442.     if (NewObj != NULL) {
  443.         *DisplayList = NewObj;
  444.     }
  445.     return;
  446.     }
  447.  
  448.     if (stricmp(Name, (*DisplayList) -> Name) == 0) {
  449.     if (Remove) {
  450.         PObj = *DisplayList;
  451.         *DisplayList = (*DisplayList) -> Pnext;
  452.         IPFreeObject(PObj);
  453.     }
  454.     else {
  455.         NewObj -> Pnext = (*DisplayList) -> Pnext;
  456.         IPFreeObject(*DisplayList);
  457.         *DisplayList = NewObj;
  458.     }
  459.     }
  460.     else {
  461.     for (PObj = *DisplayList; PObj -> Pnext != NULL; PObj = PObj -> Pnext) {
  462.         if (stricmp(Name, PObj -> Pnext -> Name) == 0) {
  463.         IPObjectStruct
  464.             *PObjTmp = PObj -> Pnext;
  465.  
  466.         if (Remove) {
  467.             PObj -> Pnext = PObjTmp -> Pnext;
  468.         }
  469.         else {
  470.             PObj -> Pnext = NewObj;
  471.             NewObj -> Pnext = PObjTmp -> Pnext;
  472.         }
  473.         IPFreeObject(PObjTmp);
  474.         return;
  475.         }
  476.     }
  477.  
  478.     /* Name was not found. */
  479.     if (!Remove) {
  480.         NewObj -> Pnext = *DisplayList;
  481.         *DisplayList = NewObj;
  482.     }
  483.     }
  484. }
  485.  
  486. /****************************************************************************
  487. * Save the current viewing matrices.                        *
  488. ****************************************************************************/
  489. void IGSaveCurrentMat(int ViewMode, char *Name)
  490. {
  491.     int    i, j;
  492.     FILE *f;
  493.  
  494.     if (Name == NULL)
  495.     Name = IG_DEFAULT_IRIT_MAT;
  496.  
  497.     if (strlen(Name) == 0 || (f = fopen(Name, "wt")) == NULL) {
  498.     IGIritBeep();
  499.     return;
  500.     }
  501.  
  502.     fprintf(f, "[OBJECT MATRICES\n    [OBJECT VIEW_MAT\n\t[MATRIX");
  503.     for (i = 0; i < 4; i++) {
  504.     fprintf(f, "\n\t    ");
  505.     for (j = 0; j < 4; j++)
  506.         fprintf(f, "%12.9lf ", IritPrsrViewMat[i][j]);
  507.     }
  508.     fprintf(f, "\n\t]\n    ]\n");
  509.  
  510.     if (ViewMode == IG_VIEW_PERSPECTIVE) {
  511.     fprintf(f, "    [OBJECT PRSP_MAT\n\t[MATRIX");
  512.     for (i = 0; i < 4; i++) {
  513.         fprintf(f, "\n\t    ");
  514.         for (j = 0; j < 4; j++)
  515.         fprintf(f, "%12.9lf ", IritPrsrPrspMat[i][j]);
  516.     }
  517.     fprintf(f, "\n\t]\n    ]\n");
  518.     }
  519.  
  520.     fprintf(f, "]\n");
  521.  
  522.     fclose(f);
  523. }
  524.  
  525. /******************************************************************************
  526. * Process the given event. Returns TRUE if redraw of view window is needed    *
  527. ******************************************************************************/
  528. int IGProcessEvent(IGGraphicEventType Event, RealType ChangeFactor)
  529. {
  530.     int UpdateView = TRUE;
  531.     MatrixType Mat;
  532.  
  533.     MatGenUnitMat(Mat);
  534.  
  535.     switch (Event) {
  536.     case IG_EVENT_SCR_OBJ_TGL:    /* Its Coordinate system - toggle it. */
  537.         UpdateView = FALSE;
  538.         break;
  539.     case IG_EVENT_PERS_ORTHO_TGL:          /* Its View mode - toggle it. */
  540.         break;
  541.     case IG_EVENT_PERS_ORTHO_Z: /* Its Perspective Z focal point modif. */
  542.         if (IGGlblViewMode != IG_VIEW_PERSPECTIVE) {
  543.         IGIritBeep();
  544.         UpdateView = FALSE;
  545.         break;
  546.         }
  547.         /* Make it between 0.5 and 1.5: */
  548.         ChangeFactor = ChangeFactor / 2.0 + 1.0;
  549.         IritPrsrPrspMat[2][2] *= ChangeFactor;
  550.         IritPrsrPrspMat[2][3] *= ChangeFactor;
  551.         IritPrsrPrspMat[3][2] *= ChangeFactor;
  552.         break;
  553.     case IG_EVENT_ROTATE_X:           /* Its rotation along the X axis. */
  554.         MatGenMatRotX1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
  555.         break;
  556.     case IG_EVENT_ROTATE_Y:           /* Its rotation along the Y axis. */
  557.         MatGenMatRotY1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
  558.         break;
  559.     case IG_EVENT_ROTATE_Z:           /* Its rotation along the Z axis. */
  560.         MatGenMatRotZ1(DEG2RAD(ChangeFactor * MAX_ROTATE_ANGLE), Mat);
  561.         break;
  562.     case IG_EVENT_TRANSLATE_X:    /* Its translation along the X axis. */
  563.         MatGenMatTrans(ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0, 0.0, Mat);
  564.         break;
  565.     case IG_EVENT_TRANSLATE_Y:    /* Its translation along the Y axis. */
  566.         MatGenMatTrans(0.0, ChangeFactor * MAX_TRANSLATE_FACTOR, 0.0, Mat);
  567.         break;
  568.     case IG_EVENT_TRANSLATE_Z:    /* Its translation along the Z axis. */
  569.         MatGenMatTrans(0.0, 0.0, ChangeFactor * MAX_TRANSLATE_FACTOR, Mat);
  570.         break;
  571.     case IG_EVENT_SCALE:              /* Its scaling along all axes. */
  572.         if (ChangeFactor > 0.0)              /* Make it around 1... */
  573.             ChangeFactor = ChangeFactor * MAX_SCALE_FACTOR + 1.0;
  574.         else
  575.             ChangeFactor = 1.0 / (-ChangeFactor * MAX_SCALE_FACTOR + 1.0);
  576.         MatGenMatScale(ChangeFactor, ChangeFactor, ChangeFactor, Mat);
  577.         break;
  578.     case IG_EVENT_NEAR_CLIP:             /* Near plane clipping. */
  579.         IGGlblZMinClip += ChangeFactor * MAX_CLIP_FACTOR;
  580.         break;
  581.     case IG_EVENT_FAR_CLIP:                      /* Far plane clipping. */
  582.         IGGlblZMaxClip += ChangeFactor * MAX_CLIP_FACTOR;
  583.         break;
  584.     case IG_EVENT_DEPTH_CUE:
  585.         break;
  586.     case IG_EVENT_SAVE_MATRIX:
  587.         IGSaveCurrentMat(IGGlblViewMode, NULL);
  588.         UpdateView = FALSE;
  589.         break;
  590.     case IG_EVENT_PUSH_MATRIX:
  591.         GEN_COPY(PushViewMat, IritPrsrViewMat, sizeof(MatrixType));
  592.         GEN_COPY(PushPrspMat, IritPrsrPrspMat, sizeof(MatrixType));
  593.         break;
  594.     case IG_EVENT_POP_MATRIX:
  595.         GEN_COPY(IritPrsrViewMat, PushViewMat, sizeof(MatrixType));
  596.         GEN_COPY(IritPrsrPrspMat, PushPrspMat, sizeof(MatrixType));
  597.         break;
  598.     case IG_EVENT_STATE:
  599.         IGCreateStateMenu();
  600.         break;
  601.     default:
  602.         IGIritBeep();
  603.         UpdateView = FALSE;
  604.     }
  605.  
  606.     if (UpdateView) {
  607.     switch (IGGlblTransformMode) {/* Udpate the global viewing matrix. */
  608.         case IG_TRANS_SCREEN:
  609.             MatMultTwo4by4(IritPrsrViewMat, IritPrsrViewMat, Mat);
  610.         break;
  611.         case IG_TRANS_OBJECT:
  612.         MatMultTwo4by4(IritPrsrViewMat, Mat, IritPrsrViewMat);
  613.         break;
  614.     }
  615.     }
  616.     return UpdateView;
  617. }
  618.  
  619. /******************************************************************************
  620. * Free the attribute named Name from all objects in the IGGlblDisplayList.    *
  621. ******************************************************************************/
  622. void IGActiveListFreeNamedAttribute(char *Name)
  623. {
  624.     IPObjectStruct
  625.     *PObj = IGGlblDisplayList;
  626.  
  627.     for (; PObj != NULL; PObj = PObj -> Pnext) {
  628.     AttrFreeOneAttribute(&PObj -> Attrs, Name);
  629.     }
  630. }
  631.  
  632. /******************************************************************************
  633. * Handle the event of a pop up window.                          *
  634. ******************************************************************************/
  635. int IGDefaultStateHandler(int State, int Refresh)
  636. {
  637.     int UpdateView = TRUE;
  638.  
  639.     switch (State) {
  640.     case IG_STATE_MORE_SENSITIVE:
  641.         IGGlblChangeFactor *= 2.0;
  642.         break;
  643.     case IG_STATE_LESS_SENSITIVE:
  644.         IGGlblChangeFactor *= 0.5;
  645.         break;
  646.     case IG_STATE_SCR_OBJ_TGL:
  647.         IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ?
  648.                              IG_TRANS_SCREEN :
  649.                              IG_TRANS_OBJECT;
  650.         UpdateView = FALSE;
  651.         break;
  652.     case IG_STATE_PERS_ORTHO_TGL:
  653.         IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  654.                            IG_VIEW_ORTHOGRAPHIC :
  655.                            IG_VIEW_PERSPECTIVE;
  656.         break;
  657.     case IG_STATE_DEPTH_CUE:
  658.         IGGlblDepthCue = !IGGlblDepthCue;
  659.         break;
  660.     case IG_STATE_DRAW_INTERNAL:
  661.         IGGlblDrawInternal = !IGGlblDrawInternal;
  662.         break;
  663.     case IG_STATE_DRAW_VNORMAL:
  664.         IGGlblDrawVNormal = !IGGlblDrawVNormal;
  665.         break;
  666.     case IG_STATE_DRAW_PNORMAL:
  667.         IGGlblDrawPNormal = !IGGlblDrawPNormal;
  668.         break;
  669.     case IG_STATE_DRAW_SRF_MESH:
  670.         IGGlblDrawSurfaceMesh = !IGGlblDrawSurfaceMesh;
  671.         break;
  672.     case IG_STATE_DRAW_SRF_POLY:
  673.         IGGlblDrawSurfacePoly = !IGGlblDrawSurfacePoly;
  674.         break;
  675.     case IG_STATE_FOUR_PER_FLAT:
  676.         IGGlblFourPerFlat = !IGGlblFourPerFlat;
  677.         IGActiveListFreeNamedAttribute("_polygons");
  678.         break;
  679.     case IG_STATE_MORE_ISOLINES:
  680.         IGGlblNumOfIsolines *= 2;
  681.         IGActiveListFreeNamedAttribute("_isoline");
  682.         break;
  683.     case IG_STATE_LESS_ISOLINES:
  684.         IGGlblNumOfIsolines /= 2;
  685.         if (IGGlblNumOfIsolines < 2)
  686.         IGGlblNumOfIsolines = 2;
  687.         IGActiveListFreeNamedAttribute("_isoline");
  688.         break;
  689.     case IG_STATE_LONGER_VECTORS:
  690.         IGGlblNormalLen *= 2.0;
  691.         break;
  692.     case IG_STATE_SHORTER_VECTORS:
  693.         IGGlblNormalLen /= 2.0;
  694.         break;
  695.     case IG_STATE_FINER_APPROX:
  696.         IGGlblSamplesPerCurve++;
  697.         IGGlblFineNess++;
  698.         IGActiveListFreeNamedAttribute("_polygons");
  699.         IGActiveListFreeNamedAttribute("_isoline");
  700.         break;
  701.     case IG_STATE_COARSER_APPROX:
  702.         IGGlblFineNess--;
  703.         if (IGGlblFineNess < 2)
  704.         IGGlblFineNess = 2;
  705.         IGGlblSamplesPerCurve--;
  706.         if (IGGlblSamplesPerCurve < 2)
  707.         IGGlblSamplesPerCurve = 2;
  708.         IGActiveListFreeNamedAttribute("_polygons");
  709.         IGActiveListFreeNamedAttribute("_isoline");
  710.         break;
  711.     case IG_STATE_VIEW_FRONT:
  712.         IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC;
  713.         MatGenUnitMat(IritPrsrViewMat);
  714.         break;
  715.     case IG_STATE_VIEW_SIDE:
  716.         IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC;
  717.         MatGenMatRotY1(DEG2RAD(90.0), IritPrsrViewMat);
  718.         break;
  719.     case IG_STATE_VIEW_TOP:
  720.         IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC;
  721.         MatGenMatRotX1(DEG2RAD(90.0), IritPrsrViewMat);
  722.         break;
  723.     case IG_STATE_VIEW_ISOMETRY:
  724.         IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC;
  725.         GEN_COPY(IritPrsrViewMat, IsometryViewMat, sizeof(MatrixType));
  726.         break;
  727.     default:
  728.         UpdateView = FALSE;
  729.         break;
  730.     }
  731.  
  732.     return UpdateView;
  733. }
  734.